package com.mef.smsplat.service;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import com.cqcis.base.utils.BeanUtils;
import com.hc24.util.BeanUtilsEx;
import com.hc24.util.IDUtil;
import com.hc24.util.ObjectUtil;
import com.mef.smsplat.dao.SmsHistoryInfoDao;
import com.mef.smsplat.dao.SmsOpraInfoDao;
import com.mef.smsplat.dao.base.DataGridModel;
import com.mef.smsplat.dao.base.EntityDao;
import com.mef.smsplat.dao.base.Page;
import com.mef.smsplat.domain.SmsHistoryInfoDomain;
import com.mef.smsplat.domain.SmsOpraInfoDomain;
import com.mef.smsplat.eterm.Detr;
import com.mef.smsplat.eterm.Rt;
import com.mef.smsplat.eterm.bean.DetrResult;
import com.mef.smsplat.eterm.bean.PNRPasseenger;
import com.mef.smsplat.eterm.bean.PNRSeg;
import com.mef.smsplat.eterm.bean.PNRTicket;
import com.mef.smsplat.eterm.bean.RtResult;
import com.mef.smsplat.exception.BusinessException;
import com.mef.smsplat.service.base.BaseService;
import com.mef.smsplat.service.vo.PassengerVo;
import com.mef.smsplat.util.AirportUtil;
import com.mef.smsplat.util.Constants;
import com.mef.smsplat.util.FreeMarkerUtil;
import com.mef.smsplat.util.SmsUtil;
import com.mef.smsplat.web.controller.qo.SmsHistoryQo;
import com.sun.org.apache.commons.beanutils.PropertyUtils;


/**
 * 旅客信息提取&短信发送业务服务类
 * @author hc24
 *
 */
@Service
@Transactional
public class SmsHistoryInfoService extends BaseService<SmsHistoryInfoDomain, String> {
	private static final Log logger=LogFactory.getLog(SmsHistoryInfoService.class);
	private SmsHistoryInfoDao smsHistoryInfoDao;
	private SmsOpraInfoDao smsOpraInfoDao;
	private FreeMarkerConfigurer freeMarker;
	private CacheManager cacheManager;
	
	public void setSmsHistoryInfoDao(SmsHistoryInfoDao smsHistoryInfoDao) {
		this.smsHistoryInfoDao = smsHistoryInfoDao;
	}

	public void setSmsOpraInfoDao(SmsOpraInfoDao smsOpraInfoDao) {
		this.smsOpraInfoDao = smsOpraInfoDao;
	}


	public void setFreeMarker(FreeMarkerConfigurer freeMarker) {
		this.freeMarker = freeMarker;
	}

	public void setCacheManager(CacheManager cacheManager) {
		this.cacheManager = cacheManager;
	}
	
	public Page<SmsHistoryInfoDomain> query(SmsHistoryQo qo,DataGridModel dgm){
		return smsHistoryInfoDao.query(qo, dgm);
	}

	/**
	 * 根据PNR提取旅客信息
	 * @param pnr pnr编码
	 * @return
	 */
	public List<PassengerVo> rtPass(String pnr){
		Rt rt=new Rt();
		RtResult rtResult= rt.rt(pnr);
		logger.debug(rtResult);
		if(rtResult==null)
			throw new BusinessException("RT:"+pnr+"没有信息");
		List<PNRPasseenger> pnrPasseengers= rtResult.getPasseengerList();
		if(pnrPasseengers==null||pnrPasseengers.size()==0)
			throw new BusinessException("RT:"+pnr+"没有信息");
		
		List<PassengerVo> list=new ArrayList<PassengerVo>();
		for(int i=0;i<pnrPasseengers.size();i++){
			PNRPasseenger pnrPasseenger=pnrPasseengers.get(i);
			PassengerVo vo=new PassengerVo();
			String flightNo="";
			String flightDate="";
			String flightTime="";
			String segment="";
			String segmentCh="";
			String cabin="";
			String term="";
			for(int j=0;j<rtResult.getSegsList().size();j++){
				PNRSeg pnrSeg=rtResult.getSegsList().get(j);
				flightNo+=pnrSeg.getAirNo()+"/";
				flightDate+=pnrSeg.getSegDate()+"/";
				flightTime+=pnrSeg.getDepartureTime()+"/";
				segment+=pnrSeg.getOrgCity()+pnrSeg.getDesCity()+"/";
				segmentCh+=AirportUtil.getAirportName(pnrSeg.getOrgCity())+"-"+AirportUtil.getAirportName(pnrSeg.getDesCity())+"/";
				cabin+=pnrSeg.getCabin()+"/";
				term+=pnrSeg.getDepartureTerm()+pnrSeg.getArrivalTerm()+"/";
			}
			flightNo=flightNo.substring(0,flightNo.length()-1);
			flightDate=flightDate.substring(0,flightDate.length()-1);
			flightTime=flightTime.substring(0,flightTime.length()-1);
			segment=segment.substring(0,segment.length()-1);
			segmentCh=segmentCh.substring(0,segmentCh.length()-1);
			cabin=cabin.substring(0,cabin.length()-1);
			term=term.substring(0,term.length()-1);
			
			//在这里可以把三字码转换为真实的机场
			
			
			//电话号码
			String telphone="";
			if(rtResult.getPhoneList()!=null&&rtResult.getPhoneList().size()>0)
				telphone=rtResult.getPhoneList().get(0);
			
			//票号
			String tktNo="";
			for(int j=0;j<rtResult.getTicketList().size();j++){
				PNRTicket pnrTicket= rtResult.getTicketList().get(j);
				if(pnrTicket.getPassName().trim().equals(pnrPasseenger.getName())){
					tktNo=pnrTicket.getTicketNo();
					break;
				}
			}
			
			vo.setFlightDate(flightDate);
			vo.setFlightNo(flightNo);
			vo.setFlightTime(flightTime);
			vo.setOffice(rtResult.getOfficeCode());
			vo.setPassName(pnrPasseenger.getName());
			vo.setPnr(rtResult.getPnrCode());
			vo.setSegment(segment);
			vo.setSegmentCh(segmentCh);
			vo.setTelphone(telphone);
			vo.setCabin(cabin);
			vo.setTktNo(tktNo);
			vo.setTerm(term);
			vo.setPassId(IDUtil.next()+"");
			
			list.add(vo);
		}
		
		//把旅客数据放入缓存
		Cache cache=cacheManager.getCache("passCache");
		for(int i=0;i<list.size();i++){
			Element element = new Element(list.get(i).getPassId(), list.get(i));
			cache.put(element);
		}
		
		return list;
	}
	
	/**
	 * 根据票号提取旅客信息
	 * @param tktNo 票号
	 * @return 旅客信息，这里是个List，实际上只有一条
	 */
	public List<PassengerVo> detrPass(String tktNo){
		Detr detr=new Detr();
		DetrResult detrResult = detr.detrByTN(tktNo);
		if(detrResult==null)
			throw new BusinessException("DETR:TN/"+tktNo+" 无信息");
		String pnr=detrResult.getAirCompanyPnr();
		List<PassengerVo> passVoList=rtPass(pnr);
		List<PassengerVo> list=new ArrayList<PassengerVo>();
		for(int i=0;i<passVoList.size();i++){
			PassengerVo passVo=passVoList.get(i);
			if(passVo.getTktNo().replaceAll("-", "").equals(tktNo.replaceAll("-", ""))){
				list.add(passVo);
				break;
			}
		}
		return list;
	}
	
	
	
	/**
	 * 模版预览功能
	 * @param templateId 模版ID
	 * @param passId 旅客ID
	 * @return 模版预览内容
	 */
	public String priviewTemplate(String templateId,String passId){
		Cache cache=cacheManager.getCache("passCache");
		Element e=cache.get(passId);
		if(e!=null){
			PassengerVo vo=(PassengerVo) e.getValue();
			Map<String, Object> smsMap = ObjectUtil.tranObjToMap(vo);
			return FreeMarkerUtil.processTemplateIntoString(templateId, smsMap);
		}
		return "";
	}
	
	/**
	 * 终止短信发送
	 * @param smsHistoryId
	 * @param smsOpra
	 */
	public void stopSms(String smsHistoryId,SmsOpraInfoDomain smsOpra){
		SmsHistoryInfoDomain smsHistory= smsHistoryInfoDao.getById(smsHistoryId);
		smsHistory.setStatus(Constants.SMS_SEND_OVER);//状态标记为终止
		smsHistoryInfoDao.update(smsHistory);
		
		smsOpra.setSmsOpraId(IDUtil.next()+"");
		smsOpra.setSmsHistoryId(smsHistoryId);
		smsOpra.setOpraTime(new Date());
		smsOpra.setOpraType(Constants.SMS_OPRA_OVER);//发送类型发送
		
		smsOpraInfoDao.save(smsOpra);
	}
	
	/**
	 * 重新发送，如果输入了新的电话号码，则生成新的一条发送记录
	 * @param smsHistoryId
	 * @param smsContent
	 * @param telphone
	 * @param smsOpra
	 */
	public String reSendSms(String smsHistoryId,String smsContent,String telphone,SmsOpraInfoDomain smsOpra){
		SmsHistoryInfoDomain domain= smsHistoryInfoDao.getById(smsHistoryId);
		
		if(domain.getStatus()!=Constants.SMS_SEND_FAIL&&domain.getStatus()!=Constants.SMS_SEND_ING)
			throw new BusinessException("发送失败和正在发送的短信才可以重发");
		if(telphone==null||"".equals(telphone)){//如果电话号码为空 更新旧的
			domain.setSmsContent(smsContent);
			domain.setStatus(Constants.SMS_SEND_ING);//更新状态为发送中
			smsHistoryInfoDao.update(domain);
			
			//生成操作责任信息
			smsOpra.setSmsOpraId(IDUtil.next()+"");
			smsOpra.setSmsHistoryId(domain.getSmsHistoryId());
			smsOpra.setOpraType(Constants.SMS_OPRA_AGAIN);//发送类型重新发送
			smsOpra.setOpraTime(new Date());//操作时间
			smsOpraInfoDao.save(smsOpra);
			
			/** 调用短信发送线程 */
			SmsUtil.sendSms(domain.getPhone(), smsContent, domain.getSmsHistoryId());
			
			return smsHistoryId;
		}else{
			SmsHistoryInfoDomain newDomain=new SmsHistoryInfoDomain();
			BeanUtils.copyProperties(domain,newDomain);
			newDomain.setSmsHistoryId(IDUtil.orderID("SMS"));
			newDomain.setStatus(Constants.SMS_SEND_ING);
			newDomain.setPhone(Constants.TELPHONE);//测试代码，上线要删除
			//newDomain.setPhone(telphone);//更新电话号码
			newDomain.setSendTime(new Date());
			smsHistoryInfoDao.save(newDomain);
			
			//生成操作责任信息
			smsOpra.setSmsOpraId(IDUtil.next()+"");
			smsOpra.setSmsHistoryId(newDomain.getSmsHistoryId());
			smsOpra.setOpraType(Constants.SMS_OPRA_SEND);//发送类型发送
			smsOpra.setOpraTime(new Date());//操作时间
			smsOpraInfoDao.save(smsOpra);
			
			/* 调用短信发送线程 */
			SmsUtil.sendSms(newDomain.getPhone(), smsContent, newDomain.getSmsHistoryId());
			
			return newDomain.getSmsHistoryId();
		}
	}
	
	/**
	 * 根据短信模版和旅客ID进行短信发送，如果内容smsContent为空，则根据模版来发送
	 * @param templateId 模版
	 * @param smsContent 短信内容
	 * @param passIds 旅客数组
	 * @param smsOpra 操作信息
	 */
	public void sendSms(String templateId,String smsContent,String[] passIds,SmsOpraInfoDomain smsOpra){
//		Template smsTpl=null;
//		try {
//			smsTpl = freeMarker.getConfiguration().getTemplate("etdz-sms.ftl");						
//		} catch (Exception e) {
//			logger.error("模版加载出错",e);
//			throw new BusinessException("模版加载出错");
//		}
		
		
		//从缓存中查找旅客数据
		Cache cache=cacheManager.getCache("passCache");
		List<PassengerVo> list=new ArrayList<PassengerVo>();
		List<String> smsHistoryIds=new ArrayList<String>();
		List<String> phones=new ArrayList<String>();
		List<String> contents=new ArrayList<String>();
		for(int i=0;i<passIds.length;i++){
			Element e=cache.get(passIds[i]);
			if(e!=null){
				PassengerVo vo=(PassengerVo) e.getValue();
				
				int status=Constants.SMS_SEND_ING;//发送状态默认就是发送中
				if(smsContent==null||"".equals(smsContent)){//判断短信内容是否为空，空则根据模版发送
					Map<String, Object> smsMap = ObjectUtil.tranObjToMap(vo);
					try {
						smsContent = FreeMarkerUtil.processTemplateIntoString(templateId, smsMap);
					} catch (Exception ee) {
						logger.info("根据模版生成短信出错",ee);	
						status=Constants.SMS_SEND_FAIL;//发送失败状态
					}
				}
				logger.debug("生成的短信内容：\n"+smsContent);
				
				//生成SmsHistoryInfoDomain并存入数据库
				SmsHistoryInfoDomain domain=new SmsHistoryInfoDomain();
				try {
					PropertyUtils.copyProperties(domain,vo);//copy属性
				} catch (Exception e1) {
					logger.info("copy旅客属性的时候出错"+e1);
				} 
				domain.setSmsHistoryId(IDUtil.orderID("SMS"));//ID
				domain.setSmsContent(smsContent);//短信内容
				domain.setSysType(Constants.SMS_TYPE_ETDZ);//出票
				domain.setStatus(status);//标志为正在发送
				domain.setTemplateId(templateId);//模版ID
				domain.setSendTime(new Date());//虽然这个时间不是很精准，差不了多少了
				domain.setPhone(Constants.TELPHONE);//临时测试代码，记得后面删除
				//domain.setPhone(vo.getTelphone());//这一句是生产代码
				
				smsHistoryInfoDao.save(domain);//保存
				
				//生成操作责任信息
				smsOpra.setSmsOpraId(IDUtil.next()+"");
				smsOpra.setSmsHistoryId(domain.getSmsHistoryId());
				smsOpra.setOpraType(Constants.SMS_OPRA_SEND);//发送类型发送
				smsOpra.setOpraTime(new Date());//操作时间
				smsOpra.setRemark("");
				
				smsOpraInfoDao.save(smsOpra);//保存历史操作
				
				smsHistoryIds.add(domain.getSmsHistoryId());
				phones.add(domain.getPhone());
				contents.add(domain.getSmsContent());
					
			}//end if
			//cache.remove(passIds[i]);//在缓存中清楚本条旅客信息
		}//end for
		
		/* 调用发送短信的线程 */
		SmsUtil.sendSms(phones.toArray(new String[]{}), contents.toArray(new String[]{}), smsHistoryIds.toArray(new String[]{}));
		
		
	}

	@Override
	protected EntityDao getEntityDao() {
		return this.smsHistoryInfoDao;
	}
	
	public static void main(String[] args) {
//		Template smsTpl=null;
//		try {
//			
//			smsTpl = freeMarker.getConfiguration().getTemplate("etdz-sms.ftl");						
//		} catch (Exception e) {
//			logger.error("模版加载出错",e);
//			throw new BusinessException("模版加载出错");
//		}
		
		
	}

}
